package com.kime.email.javamail;

import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Properties;

/**
 * 发送一封简单文本的邮件：
 * - 获取系统属性：用于配置属性
 * - 自定义验证器：实现 Authenticator 类，重写 getPasswordAuthentication() 方法
 * - 获取 Session 对象，传入自定义验证操作
 * - 创建邮件
 *      - 设置发件人电子邮箱
 *      - 设置收件人电子邮箱
 *      - 设置邮件主题
 *      - 设置邮件正文
 *      - 设置邮件发送时间
 *      - 保存邮件设置
 *      - ...
 * - 根据 session 获取邮件传输对象
 * - 连接邮件服务器
 * - 发送邮件，发送所有的收件地址
 * - 关闭连接
 */
public class SendSimpleEmail {

    // 发件人电子邮箱
    private static String from;
    // 发件人昵称
    private static String fromNickName;
    // 发件人密码/授权码
    private static String password;
    // 收件人电子邮箱
    private static String recipients;
    // 收件人昵称
    private static String recipientNickName;
    // 指定发送邮件的主机
    private static String senderHost;
    // 字符集编码
    private static String charset;
    // 邮件主题
    private static String subject;
    // 邮件正文
    private static String content;
    //邮件正文字符集编码
    private static String contentCharset;

    /**
     * 通过加载器初始加载 simpleEmailInfo.properties 文件，获取属性值
     */
    static {
        try {
            InputStream resource = ClassLoader.getSystemResourceAsStream("simpleEmailInfo.properties");
            Properties properties = new Properties();
            properties.load(resource);
            from = properties.getProperty("email.from");
            fromNickName = properties.getProperty("email.from.nickName");
            password = properties.getProperty("email.password");
            recipients = properties.getProperty("email.recipients");
            recipientNickName = properties.getProperty("email.recipient.nickName");
            senderHost = properties.getProperty("email.senderHost");
            charset = properties.getProperty("email.charset");
            subject = properties.getProperty("email.subject");
            content = properties.getProperty("email.content");
            contentCharset = properties.getProperty("email.content.charset");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送邮件操作
     */
    public void sendEmail() {
        // 获取属性：用于配置属性
        Properties properties = new Properties();
        // 配置 SMTP 协议
        properties.setProperty("mail.transport.protocol", "smtp");
        // 配置发件人邮箱的 SMTP 服务器地址
        properties.setProperty("mail.smtp.host", senderHost);
        // 配置 SMTP 服务器地址端口
        properties.put("mail.smtp.port", 25);
        // 配置请求认证
        properties.setProperty("mail.smtp.auth", "true");
        // 获取 Session 对象
        Session session = Session.getInstance(properties, new MyAuthenticator(from, password));
        // 查看发送邮件的详细信息
        session.setDebug(true);
        try {
            // 创建简单文本的邮件
            MimeMessage message = createSimpleMail(session);
            // 根据 session 获取邮件传输对象
            Transport transport = session.getTransport();
            // 连接邮件服务器
            transport.connect(from, password);
            // 发送邮件，发送所有的收件地址
            transport.sendMessage(message, message.getAllRecipients());
            // 关闭连接
            transport.close();
        } catch (Exception e) {
            System.out.println("创建邮件失败，请重新创建: "+ e.getMessage());
        }
    }

    /**
     * 创建一封简单文本的邮件
     */
    private MimeMessage createSimpleMail(Session session) throws Exception {
        // 创建邮件信息
        MimeMessage message = new MimeMessage(session);
        /*
        new InternetAddress(from, "kime", "UTF-8") ：用于设置地址：
            - address： 发件人地址
            - personal：显示昵称
            - charset： 显示昵称的字符集编码
        也可以直接设置：
        message.setFrom(from);
         */
        // 设置发件人电子邮箱
        message.setFrom(new InternetAddress(from, fromNickName, charset));
        /*
        设置收件人电子邮箱
        发送邮件方式类型：
            - MimeMessage.RecipientType.TO：收件人
            - MimeMessage.RecipientType.CC：抄送人(可选)
            - MimeMessage.RecipientType.BCC：密送人(可选)
         */
        message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(recipients, recipientNickName, charset));
        // 设置邮件主题
        message.setSubject(subject, charset);
        // 设置邮件正文
        message.setContent(content, contentCharset);
        // 设置邮件发送时间
        message.setSentDate(new Date());
        // 保存设置
        message.saveChanges();
        return message;
    }

    public static void main(String[] args) {
        SendSimpleEmail sendSimpleEmail = new SendSimpleEmail();
        sendSimpleEmail.sendEmail();
    }
}
